/* vcc/plugins/hist/hist.c 
 * 
 * This file is part of vcc. 
 * 
 * vcc is free software: you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation, either version 3 of the License, or 
 * (at your option) any later version. 
 * 
 * vcc is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 * GNU General Public License for more details. 
 * 
 * You should have received a copy of the GNU General Public License 
 * along with vcc. If not, see <https://www.gnu.org/licenses/>
 */ 




#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <limits.h>

#include <sys/types.h>
#include <sys/times.h>

#include <vcc/vcc.h>
#include <vcc/pretty.h>
#include <vcc/plugin.h>
#include <vcc/version.h>
#include <vcc/interfaces.h>
#include <klist.h>

#include <readconf/readconf.h>


int hist_init(void);
int do_cmd_hist(int argc, char **argv);
int hist_fd;

struct cmdtable hist_cmdtab[] = {
	{ "-hist", do_cmd_hist, "Dump history (from login to now). " }, 

	{ NULL, NULL, NULL }
};

struct plugin plg_hist = {
	.state = 0, 
	.name = "hist", 
	.descr = "Show history. ", 
	.init =  hist_init, 
	.cmdtab = hist_cmdtab
};

struct klist_node history = KLIST_NODE_INIT(&history);

#define this_plg (&plg_hist)
#define DEFAULT_HISTFILE ".vcc_history"

char *hist_hook(struct hook_info *hi) {
	struct history *n;

	if (unlikely(!(n = malloc(sizeof(struct history))))) {
		fprintf(stderr, "*** malloc() failed\n");

		return strdup(hi->msg);
	}

	n->usrname = strdup(hi->usr);
	n->msg = strdup(hi->msg);

	klist_init(&n->node);
	klist_add(&history, &n->node);

	dprintf(hist_fd, "[%ld] %s: %s", times(NULL), hi->usr, hi->msg);

	return HOOK_IGNORE;
}

int open_hist_file(void) {
	struct readconf_strconf *conf;
	char *p;
	char buf[PATH_MAX];

	if (!(conf = readconf_find_strname("histfile"))) {
		p = getenv("HOME");
		sprintf(buf, "%s/" DEFAULT_HISTFILE, p);
		p = buf;
	}
	
	else 
		p = conf->conf_value;

	printf("using history file %s\n", p);

	if (unlikely((hist_fd = open(p, O_WRONLY | O_APPEND | O_CREAT)) < 0)) {
		perror("open()");
		return -1;
	}

	return hist_fd;
}

int hist_init(void) {
	if (unlikely((hist_fd = open_hist_file()) < 0)) {
		fprintf(stderr, "*** unable to open history file. \n");

		return 1;
	}

	register_hook(HOOK_RECV, hist_hook);
	register_hook(HOOK_SEND, hist_hook);

	return 0;
}


int do_cmd_hist(int argc, char **argv) {
	struct klist_node *n;
	struct history *hist;

	(void) argv;

	plg_check_enabled();

	if (argc != 1) {
		fprintf(stderr, _("usage: -hist\n"));

		return 1;
	}

	for (n = history.next; n != &history; n = n->next) {
		hist = hist_of(n);

		pretty_new_msg(hist->usrname, hist->msg, 0, 0);
	}

	return 0;
}


struct history *hist_getmsg(int last) {
	struct klist_node *n;

	for (n = history.next; n != &history && last--; n = n->next) 
		;

	if (n == &history) 
		return NULL;

	return hist_of(n);
}


